package com.contactbook.web.client;

import java.util.HashMap;

import java.util.Map;

import com.contactbook.web.client.service.AccountService;
import com.contactbook.web.client.service.AccountServiceAsync;
import com.contactbook.web.client.service.ContactService;
import com.contactbook.web.client.service.ContactServiceAsync;
import com.contactbook.web.client.service.GroupService;
import com.contactbook.web.client.service.GroupServiceAsync;
import com.contactbook.web.client.session.CurrentSession;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 * 
 * ContactBook uses Mediator pattern to control each view
 */
public class ContactBook implements EntryPoint {
	
	/* Service */
	private static final AccountServiceAsync accountService = GWT.create(AccountService.class);
	private static final GroupServiceAsync groupService = GWT.create(GroupService.class);
	private static final ContactServiceAsync contactService = GWT.create(ContactService.class);
		
	private CurrentSession session;
	
	/* Mapping of each views with the name of the view */
	Map<String, View> views = new HashMap<String, View>();
	
	/* Login/Logout link */
	HorizontalPanel panelLog;
	Label labelLog;
	Label labelLogout;
	
	public ContactBook() {
		
		/* Obtain a reference to the service accountService */
		/*ServiceDefTarget endpoint1 = (ServiceDefTarget) getAccountService();
	    endpoint1.setServiceEntryPoint(GWT.getModuleBaseURL() + "account");
	    
		ServiceDefTarget endpoint2 = (ServiceDefTarget) getContactService();
	    endpoint2.setServiceEntryPoint(GWT.getModuleBaseURL() + "contact");
	    
		ServiceDefTarget endpoint3 = (ServiceDefTarget) getGroupService();
	    endpoint3.setServiceEntryPoint(GWT.getModuleBaseURL() + "group");
        */
		session = new CurrentSession();

		views.put(Constants.MyAccountViewName, new MyAccountWidget(this));
		views.put(Constants.ContactSheetViewName, new ContactSheetWidget(this));
		views.put("addContact", new AddContactWidget(this));
		views.put(Constants.DeleteContactViewName, new DeleteContactWidget(this));
		views.put("addGroup", new AddGroupWidget(this));
		views.put("deleteGroup", new DeleteGroupWidget(this));
		views.put("createAccount", new CreateAccountWidget(this));
		views.put(Constants.DeleteAccountViewName, new DeleteAccountWidget(this));
		views.put("listOfContacts", new ListOfContactsWidget(this));
		views.put(Constants.ListOfGroupsViewName, new ListOfGroupsWidget(this));
		views.put("contactDetails", new ContactDetailsWidget(this));
		views.put("welcomeUser", new WelcomeUserWidget(this));
		views.put("login", new LoginWidget(this));
		
		panelLog = new HorizontalPanel();
		labelLog = new Label("");
		labelLogout = new Label("");
		
		RootPanel.get("main-menu").add(createMenuOptions());
	}
	
	public boolean isLogged() {
		return session.isLogged();
	}
	
	public HorizontalPanel createMenuOptions() {
		HorizontalPanel optionsPanel = new HorizontalPanel();
		
		FlexTable tableOptions = new FlexTable();
	
		Label optionAccount = new Label(Constants.AccountMenuOption);
		optionAccount.setTitle(Constants.AccountMenuOptionTitle);
		optionAccount.setStyleName("gwt-label-menuOption");
		optionAccount.setHeight("22px");
		optionAccount.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent arg0) {
				switchView(Constants.MyAccountViewName);
			}			
		});
        
        Label optionContacts = new Label(Constants.ContactsMenuOption);
        optionContacts.setTitle(Constants.ContactsMenuOptionTitle);
        optionContacts.setStyleName("gwt-label-menuOption");
        optionContacts.setHeight("22px");
        optionContacts.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent arg0) {
				switchView(Constants.ListOfContactsViewName);
			}        	
        });
        
        Label optionGroups = new Label(Constants.GroupsMenuOption);
        optionGroups.setTitle(Constants.GroupMenuOptionTitle);
        optionGroups.setStyleName("gwt-label-menuOption");
        optionGroups.setHeight("22px");
        optionGroups.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent arg0) {
				switchView(Constants.ListOfGroupsViewName);
			}        	
        });
        
        panelLog.setHeight("22px");
        
        labelLog.setText("");
        labelLog.setStyleName("gwt-label-labelLog");
        
        labelLogout.setText("");
        labelLogout.setTitle("Close your contact book");
        labelLogout.setStyleName("gwt-label-labelLogout");
        labelLogout.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent arg0) {
				setLogOut();
				session.logout();
				session.parameters.clear();
				switchView(Constants.LoginViewName);
			}
		});

        panelLog.add(labelLog);
        panelLog.add(labelLogout);
        
        tableOptions.setWidget(0, 0, optionAccount);
        tableOptions.setWidget(0, 1, optionContacts);
        tableOptions.setWidget(0, 2, optionGroups);
        tableOptions.setWidget(0, 3, panelLog);
        
        tableOptions.setCellPadding(0);
        tableOptions.setCellSpacing(2);
        tableOptions.getFlexCellFormatter().setHeight(0, 0, Constants.MenuOptionHeight);
        tableOptions.getFlexCellFormatter().setAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_MIDDLE);
                
        tableOptions.getFlexCellFormatter().setHeight(0, 1, Constants.MenuOptionHeight);
        tableOptions.getFlexCellFormatter().setAlignment(0, 1, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_MIDDLE);
        
        tableOptions.getFlexCellFormatter().setHeight(0, 2, Constants.MenuOptionHeight);
        tableOptions.getFlexCellFormatter().setAlignment(0, 2, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_MIDDLE);
        
        tableOptions.getFlexCellFormatter().setHeight(0, 3, Constants.MenuOptionHeight);
        tableOptions.getFlexCellFormatter().setAlignment(0, 3, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_MIDDLE);
        
        optionsPanel.add(tableOptions);
        
		return optionsPanel;
	}
	
    public void switchView(String viewName)
    {   	
    	View view = views.get(viewName);
         
        // Clear old elements
        RootPanel.get("app-content").clear();
        RootPanel.get("app-title").clear();
         
        // Add the new form
        RootPanel.get("app-content").add(view.getContent());
                  
        // Set the new form title
        Label title = new Label();
        title.setText(view.getTitle());
        title.setStyleName("gwt-label-maintitle");
        RootPanel.get("app-title").add(title);
    }
    
    public CurrentSession getCurrentSession() {
    	return session;
    }
    
    public void setCurrentSession(CurrentSession session) {
    	this.session = session;
    }

	@Override
	public void onModuleLoad() {
		switchView("welcomeUser");
	}
	
	public AccountServiceAsync getAccountService() {
		return accountService;
	}
	
	public ContactServiceAsync getContactService() {
		return contactService;
	}

	public GroupServiceAsync getGroupService() {
		return groupService;
	}
	
	public void setLogOn() {
		labelLog.setText("Welcome " + session.getLogin() + " ");
		labelLogout.setText(Constants.LogoutLink);
		panelLog.setVisible(true);
	}
	
	public void setLogOut() {
		labelLog.setText("");
		panelLog.setVisible(false);
	}
}
